package com.victor.common.controller;

import com.baomidou.mybatisplus.plugins.Page;
import com.victor.common.constant.cache.Cache;
import com.victor.common.constant.tips.SuccessTip;
import com.victor.common.page.PageInfoBT;
import com.victor.common.persistence.dao.MenuMapper;
import com.victor.common.persistence.dao.RoleMapper;
import com.victor.common.persistence.dao.UserMapper;
import com.victor.common.persistence.dao.UsersImagesMapper;
import com.victor.common.warpper.BaseControllerWarpper;
import com.victor.config.properties.VictorProperties;
import com.victor.core.cache.CacheKit;
import com.victor.core.support.HttpKit;
import com.victor.core.util.Arith;
import com.victor.core.util.FileUtil;
import com.victor.core.util.RedisClient;
import com.victor.modular.system.dao.LogDao;
import com.victor.modular.system.dao.MenuDao;
import com.victor.modular.system.dao.RoleDao;
import com.victor.modular.system.dao.UserMgrDao;
import com.victor.modular.system.service.IMenuService;
import com.victor.modular.system.service.IRoleService;
import com.victor.modular.system.service.IUserService;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Set;

/**
 * BaseController
 */
@Controller
public class BaseController {
    protected final static Logger logger = LoggerFactory.getLogger(BaseController.class);

    /* redis */
    @Resource
    protected RedisClient redisClient;
    /* 模板配置 */
    @Resource
    protected VictorProperties victorProperties;
    protected static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
    /* 菜单 */
    @Resource
    protected MenuDao menuDao;
    @Resource
    protected MenuMapper menuMapper;
    @Resource
    protected IMenuService menuService;

    /* 用户 */
    @Resource
    protected UserMapper userMapper;
    @Resource
    protected UserMgrDao managerDao;
    @Resource
    protected IUserService userService;

    /*日志*/
    @Resource
    protected LogDao logDao;

    /*角色*/
    @Resource
    protected RoleMapper roleMapper;
    @Resource
    protected RoleDao roleDao;
    @Resource
    protected IRoleService roleService;

    @Resource
    protected UsersImagesMapper usersImagesMapper;




    /**
     * success
     */
    public static String SUCCESS = "SUCCESS";

    /**
     * error
     */
    public static String ERROR = "ERROR";

    /**
     * redirect
     */
    public static String REDIRECT = "redirect:";

    /**
     * forward
     */
    public static String FORWARD = "forward:";

    /**
     * 返回给前台的成功提示
     */
    public static SuccessTip SUCCESS_TIP = new SuccessTip();

    /**
     * <b>Description:获取request</b><br>
     *
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:50:36 <br>
     * <b>Version:</b> 1.0
     */
    public HttpServletRequest getHttpServletRequest() {
        return HttpKit.getRequest();
    }

    /**
     * <b>Description:获取response</b><br>
     *
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:50:48 <br>
     * <b>Version:</b> 1.0
     */
    public HttpServletResponse getHttpServletResponse() {
        return HttpKit.getResponse();
    }

    /**
     * <b>Description:获取session</b><br>
     *
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:50:56 <br>
     * <b>Version:</b> 1.0
     */
    public HttpSession getSession() {
        return HttpKit.getRequest().getSession();
    }

    /**
     * <b>Description:获取session 根据flag</b><br>
     *
     * @param flag
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:51:06 <br>
     * <b>Version:</b> 1.0
     */
    public HttpSession getSession(Boolean flag) {
        return HttpKit.getRequest().getSession(flag);
    }

    /**
     * <b>Description:获取参数</b><br>
     *
     * @param name
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:51:30 <br>
     * <b>Version:</b> 1.0
     */
    public String getPara(String name) {
        return HttpKit.getRequest().getParameter(name);
    }

    /**
     * <b>Description:设置参数</b><br>
     *
     * @param name
     * @param value
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:51:37 <br>
     * <b>Version:</b> 1.0
     */
    public void setAttr(String name, Object value) {
        HttpKit.getRequest().setAttribute(name, value);
    }

    /**
     * <b>Description:获取系统活跃数</b><br>
     *
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:51:49 <br>
     * <b>Version:</b> 1.0
     */
    public Integer getSystemInvokCount() {
        return (Integer) this.getHttpServletRequest().getServletContext().getAttribute("systemCount");
    }

    /**
     * <b>Description:把service层的分页信息，封装为bootstrap table通用的分页封装</b><br>
     *
     * @param page
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:52:07 <br>
     * <b>Version:</b> 1.0
     */
    public <T> PageInfoBT<T> packForBT(Page<T> page) {
        return new PageInfoBT<T>(page);
    }

    /**
     * <b>Description:包装一个list，让list增加额外属性</b><br>
     *
     * @param warpper
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:52:14 <br>
     * <b>Version:</b> 1.0
     */
    public Object warpObject(BaseControllerWarpper warpper) {
        return warpper.warp();
    }

    /**
     * <b>Description:删除cookie</b><br>
     *
     * @param cookieName
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:52:22 <br>
     * <b>Version:</b> 1.0
     */
    public void deleteCookieByName(String cookieName) {
        Cookie[] cookies = this.getHttpServletRequest().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(cookieName)) {
                Cookie temp = new Cookie(cookie.getName(), "");
                temp.setMaxAge(0);
                this.getHttpServletResponse().addCookie(temp);
            }
        }
    }

    /**
     * <b>Description:返回前台文件流</b><br>
     *
     * @param fileName
     * @param filePath
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:52:30 <br>
     * <b>Version:</b> 1.0
     */
    public ResponseEntity<byte[]> renderFile(String fileName, String filePath, boolean open) {
        byte[] bytes = FileUtil.toByteArray(filePath);
        return renderFile(fileName, bytes, open);
    }

    /**
     * <b>Description:返回前台文件流</b><br>
     *
     * @param fileName
     * @param fileBytes
     * @return
     * @Note <b>Author:</b>zhaojiabin</a> <br>
     * <b>Date:</b> 2017年10月18日 上午9:52:36 <br>
     * <b>Version:</b> 1.0
     */
    public ResponseEntity<byte[]> renderFile(String fileName, byte[] fileBytes, boolean open) {
        String dfileName = null;
        try {
            dfileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        HttpHeaders headers = new HttpHeaders();
        if (!open) {
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", dfileName);
        }
        return new ResponseEntity<byte[]>(fileBytes, headers, HttpStatus.CREATED);
    }

    /**
     * @Auther:Victor
     * @Description:清楚缓存
     * @Date:Create in 14:10 2018/4/11
     * @Modified By:
     */
    protected void clearCache(String key) {
        CacheKit.remove(Cache.CONSTANT, key);
        try {
           // logger.info("移除缓存KEY：" + key);
            redisClient.del(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Auther:Victor
     * @Description:移除所有缓存
     * @Date:Create in 10:43 2018/5/18
     * @Modified By:
     */
    protected void clearAllCache() throws Exception {
        CacheKit.removeAll(Cache.CONSTANT);
        String key = Cache.CONSTANT + "~keys";
        Set<String> set = redisClient.zrange(key, 0, -1);
        //logger.info("Ehcache缓存数量：" + set.size());
        for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
            String next = it.next();
            redisClient.del(next);
           // logger.info("移除Ehcache缓存：" + next);
        }
        long count = redisClient.zremrangeByRank(key, 0, -1);
        //logger.info("清空Ehcache缓存：" + count);
    }

    public final static long IMAGE_BASE_SIZE = 200 * 1024;

    /**
     * @Auther:Victor
     * @Description:加工图片
     * @Date:Create in 13:30 2018/4/21
     * @Modified By:
     */
    protected String processFile(File file, String newFileName, String fileRoot) throws Exception {
        File compressFile = null;
        long fileLength = file.length();//文件长度
        if (file.length() > IMAGE_BASE_SIZE) { //超过200Kb的图片进行压缩
            compressFile = new File(file.getPath());
            //对文件进行压缩
            try {
                Thumbnails.of(file)
                        .scale(Arith.div(IMAGE_BASE_SIZE, fileLength, 2))
                        //.size(160, 160)
                        //.rotate(90)
                        //.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("watermark.png")), 0.5f)
                        //.outputQuality(0.5f)
                        .outputQuality(1f)
                        .toFile(compressFile);
            } catch (IOException e) {
                e.printStackTrace();
                throw new Exception(e.getMessage());
            }
        }
        return compressFile == null ? FileUtil.moveFile(file, newFileName, fileRoot) : FileUtil.moveFile(compressFile, newFileName, fileRoot);
    }

}